home *** CD-ROM | disk | FTP | other *** search
/ Delphi Magazine Collection 2001 / Delphi Magazine Collection 20001 (2001).iso / DISKS / ISSUE20 / CONSTRUC / SPAGETTI.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1997-03-12  |  2.9 KB  |  135 lines

  1. unit spagetti;
  2. {$DEFINE ROOM}
  3. interface
  4. uses
  5.   Classes, Gauges;
  6.  
  7. const
  8.   MaxPlate = 3;
  9.  
  10. type
  11.   TSpagettiThread = class(TThread)
  12.   private
  13.     { Private declarations }
  14.     Plate: Integer;
  15.     FoodValue,Sticks: Integer; { 0..100 }
  16.     Food: TGauge;
  17.   public
  18.     constructor Create(ID: Integer; Gauge: TGauge);
  19.   protected
  20.     procedure Execute; override;
  21.   private
  22.     procedure ShowFood;
  23.     procedure Wait(Chop: Integer);
  24.     procedure Signal(Chop: Integer);
  25.   end;
  26.  
  27. implementation
  28. uses
  29.   Graphics;
  30.  
  31. var
  32.   Chopstick: Array[0..MaxPlate] of Integer; { -1 = FREE }
  33.   Room: Word;
  34.  
  35. { Important: Methods and properties of objects in VCL can only be used in a
  36.   method called using Synchronize, for example,
  37.  
  38.       Synchronize(UpdateCaption);
  39.  
  40.   and UpdateCaption could look like,
  41.  
  42.     procedure TSpagettiThread.UpdateCaption;
  43.     begin
  44.       Form1.Caption := 'Updated in a thread';
  45.     end; }
  46.  
  47. { TSpagettiThread }
  48.  
  49. constructor TSpagettiThread.Create(ID: Integer; Gauge: TGauge);
  50. begin
  51.   inherited Create(False);
  52.   Plate := ID;
  53.   Food := Gauge;
  54.   FoodValue := 100;
  55. end {Create};
  56.  
  57. procedure TSpagettiThread.ShowFood;
  58. begin
  59.   Food.Progress := FoodValue;
  60.   case Sticks of
  61.     1: Food.ForeColor := clNavy;
  62.     2: Food.ForeColor := clYellow;
  63.     else Food.ForeColor := clGray;
  64.   end;
  65.   if FoodValue <= 0 then Food.Visible := False
  66. end {ShowFood};
  67.  
  68. procedure TSpagettiThread.Wait(Chop: Integer);
  69. var i: Integer;
  70. begin
  71.   if Chopstick[Chop] >= 0 then
  72.   begin
  73.     repeat
  74.       for i:=1 to 10000 do if (i div 10000) = 1 then Dec(FoodValue);
  75.       Synchronize(ShowFood) { wait }
  76.     until (Chopstick[Chop] < 0) or (FoodValue <= 0)
  77.   end;
  78.   if FoodValue > 0 then
  79.   begin
  80.     Chopstick[Chop] := Plate { taken by me };
  81.     Inc(Sticks)
  82.   end
  83. end {Wait};
  84.  
  85. procedure TSpagettiThread.Signal(Chop: Integer);
  86. begin
  87.   if Chopstick[Chop] = Plate then { did I take it? }
  88.   begin
  89.     Chopstick[Chop] := -1 { release fork again };
  90.     Dec(Sticks)
  91.   end
  92. end {Signal};
  93.  
  94. procedure TSpagettiThread.Execute;
  95. var i: Integer;
  96. begin
  97.   { Place thread code here }
  98.   repeat
  99.     for i:=1 to 50000 do if (i mod 10000) = 0 then Dec(FoodValue);
  100.     Synchronize(ShowFood);
  101.   {$IFDEF ROOM}
  102.     if Room > 1 then
  103.     begin
  104.       Dec(Room);
  105.   {$ENDIF}
  106.       Wait(Plate);
  107.       Synchronize(ShowFood);
  108.       if FoodValue > 0 then
  109.       begin
  110.         Wait((Plate+1) mod MaxPlate);
  111.         if FoodValue > 0 then
  112.           for i:=1 to 10000 do
  113.             if (i div 10000) = 1 then FoodValue := 100; { eat }
  114.         Synchronize(ShowFood);
  115.         Signal((Plate+1) mod MaxPlate);
  116.         Synchronize(ShowFood)
  117.       end;
  118.       Signal(Plate);
  119.       Synchronize(ShowFood);
  120.   {$IFDEF ROOM}
  121.       Inc(Room)
  122.     end
  123.   {$ENDIF}
  124.   until Terminated or (FoodValue <= 0)
  125. end {Execute};
  126.  
  127.  
  128. var i: Integer;
  129. begin
  130.   for i:=0 to MaxPlate do Chopstick[i] := -1;
  131. {$IFDEF ROOM}
  132.   Room := MaxPlate
  133. {$ENDIF}
  134. end.
  135.